#!/usr/bin/env python3
"""
数据迁移测试
测试从旧版本到新版本的数据迁移功能
"""
import sys
import os
import unittest
import json
import tempfile
import shutil
from datetime import datetime

# 添加backend目录到路径
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'backend'))

from database import DatabaseManager
from workspace_service import workspace_service, session_service

class TestDataMigration(unittest.TestCase):
    """数据迁移测试类"""
    
    def setUp(self):
        """测试前准备"""
        # 创建临时目录
        self.temp_dir = tempfile.mkdtemp()
        self.test_db_path = os.path.join(self.temp_dir, 'test.db')
        
        # 初始化数据库
        self.db_manager = DatabaseManager(f'sqlite:///{self.test_db_path}')
        
        # 替换全局数据库管理器
        import workspace_service as ws_module
        ws_module.db_manager = self.db_manager
    
    def tearDown(self):
        """测试后清理"""
        shutil.rmtree(self.temp_dir)
    
    def test_legacy_data_import(self):
        """测试旧版本数据导入"""
        # 模拟旧版本的分析数据格式
        legacy_analysis_data = {
            "timestamp": "2024-01-01T10:00:00Z",
            "total_logs": 1500,
            "unique_components": 12,
            "duplicate_ratio": 23.5,
            "duplicate_count": 352,
            "most_active_components": [
                ["bmc_core", {"count": 800, "errors": 50}],
                ["network_adapter", {"count": 400, "errors": 20}]
            ],
            "most_frequent_errors": [
                ["memory_error", [
                    {"timestamp": "2024-01-01T10:05:00", "message": "Memory allocation failed"},
                    {"timestamp": "2024-01-01T10:10:00", "message": "Out of memory"}
                ]],
                ["network_error", [
                    {"timestamp": "2024-01-01T10:15:00", "message": "Connection timeout"}
                ]]
            ],
            "time_patterns": {
                "peak_hours": ["10:00", "14:00", "18:00"],
                "error_distribution": {
                    "morning": 30,
                    "afternoon": 45,
                    "evening": 25
                }
            }
        }
        
        # 创建工作区
        workspace = workspace_service.create_workspace(
            name="迁移测试工作区",
            description="用于测试数据迁移的工作区"
        )
        
        # 创建分析会话并导入旧数据
        session = session_service.create_session(
            workspace_id=workspace['id'],
            name="迁移的分析会话",
            description="从旧版本迁移的数据"
        )
        
        # 将旧格式数据转换为新格式
        migrated_analysis_results = {
            "total_logs": legacy_analysis_data["total_logs"],
            "unique_components": legacy_analysis_data["unique_components"],
            "duplicate_ratio": legacy_analysis_data["duplicate_ratio"],
            "duplicate_count": legacy_analysis_data["duplicate_count"],
            "most_active_components": legacy_analysis_data["most_active_components"],
            "most_frequent_errors": legacy_analysis_data["most_frequent_errors"],
            "time_patterns": legacy_analysis_data["time_patterns"],
            "components": self._extract_components_from_legacy(legacy_analysis_data),
            "error_categories": self._extract_error_categories_from_legacy(legacy_analysis_data)
        }
        
        # 更新会话数据
        updated_session = session_service.update_session(
            session['id'],
            analysis_results=migrated_analysis_results,
            status="completed",
            tags=["migrated", "legacy"],
            notes=f"从旧版本迁移，原始时间戳: {legacy_analysis_data['timestamp']}"
        )
        
        # 验证迁移结果
        self.assertEqual(updated_session['analysis_results']['total_logs'], 1500)
        self.assertEqual(updated_session['analysis_results']['unique_components'], 12)
        self.assertEqual(updated_session['status'], "completed")
        self.assertIn("migrated", updated_session['tags'])
        
        # 验证数据完整性
        retrieved_session = session_service.get_session(session['id'])
        self.assertEqual(
            retrieved_session['analysis_results']['total_logs'],
            legacy_analysis_data['total_logs']
        )
        
        print("[PASS] 旧版本数据导入测试通过")
    
    def _extract_components_from_legacy(self, legacy_data):
        """从旧格式中提取组件数据"""
        components = {}
        for component_name, component_data in legacy_data["most_active_components"]:
            components[component_name] = {
                "count": component_data["count"],
                "errors": component_data["errors"],
                "category": self._guess_component_category(component_name)
            }
        return components
    
    def _extract_error_categories_from_legacy(self, legacy_data):
        """从旧格式中提取错误分类数据"""
        error_categories = {}
        for error_type, error_logs in legacy_data["most_frequent_errors"]:
            error_categories[error_type] = error_logs
        return error_categories
    
    def _guess_component_category(self, component_name):
        """根据组件名称猜测分类"""
        if "bmc" in component_name.lower():
            return "framework"
        elif "network" in component_name.lower():
            return "hardware"
        else:
            return "system"
    
    def test_batch_migration(self):
        """测试批量数据迁移"""
        # 创建工作区
        workspace = workspace_service.create_workspace("批量迁移测试工作区")
        
        # 模拟多个旧分析结果
        legacy_results = []
        for i in range(5):
            legacy_results.append({
                "session_name": f"历史会话 {i+1}",
                "timestamp": f"2024-01-0{i+1}T10:00:00Z",
                "total_logs": 1000 + i * 100,
                "error_count": 10 + i * 5,
                "components": {
                    "app": 500 + i * 50,
                    "framework": 300 + i * 30,
                    "system": 200 + i * 20
                }
            })
        
        # 批量创建会话
        migrated_sessions = []
        for i, legacy_result in enumerate(legacy_results):
            session = session_service.create_session(
                workspace_id=workspace['id'],
                name=legacy_result["session_name"],
                description=f"批量迁移的会话 {i+1}"
            )
            
            # 转换并更新数据
            analysis_results = {
                "total_logs": legacy_result["total_logs"],
                "error_count": legacy_result["error_count"],
                "components": legacy_result["components"]
            }
            
            updated_session = session_service.update_session(
                session['id'],
                analysis_results=analysis_results,
                status="completed",
                tags=["batch_migrated"],
                notes=f"批量迁移，原始时间: {legacy_result['timestamp']}"
            )
            
            migrated_sessions.append(updated_session)
        
        # 验证批量迁移结果
        all_sessions = session_service.get_sessions(workspace_id=workspace['id'])
        self.assertEqual(len(all_sessions), 5)
        
        # 验证每个会话的数据
        for session in all_sessions:
            self.assertEqual(session['status'], "completed")
            self.assertIn("batch_migrated", session['tags'])
            self.assertIsNotNone(session['analysis_results'])
        
        print("[PASS] 批量数据迁移测试通过")
    
    def test_configuration_migration(self):
        """测试配置数据迁移"""
        # 模拟旧版本的配置文件
        legacy_rules_config = {
            "component_categories": {
                "framework": ["bmc_core", "bmc_api"],
                "hardware": ["network_adapter", "storage"]
            },
            "error_categories": {
                "critical": ["memory_error", "system_crash"],
                "warning": ["network_timeout", "disk_full"]
            }
        }
        
        legacy_ai_config = {
            "provider": "openai",
            "model": "gpt-3.5-turbo",
            "api_key": "sk-test-key",
            "temperature": 0.7
        }
        
        # 创建工作区
        workspace = workspace_service.create_workspace("配置迁移测试工作区")
        
        # 迁移配置到新格式
        # 在实际应用中，这些配置会保存到UserConfig表
        with self.db_manager.get_session() as session:
            from models import UserConfig
            
            # 迁移规则配置
            rules_config = UserConfig(
                workspace_id=workspace['id'],
                config_type='rules',
                config_data=legacy_rules_config
            )
            session.add(rules_config)
            
            # 迁移AI配置
            ai_config = UserConfig(
                workspace_id=workspace['id'],
                config_type='ai_config',
                config_data=legacy_ai_config
            )
            session.add(ai_config)
            
            session.commit()
        
        # 验证配置迁移
        with self.db_manager.get_session() as session:
            from models import UserConfig
            
            # 检查规则配置
            rules = session.query(UserConfig).filter(
                UserConfig.workspace_id == workspace['id'],
                UserConfig.config_type == 'rules'
            ).first()
            
            self.assertIsNotNone(rules)
            self.assertEqual(
                rules.config_data['component_categories']['framework'],
                ["bmc_core", "bmc_api"]
            )
            
            # 检查AI配置
            ai_cfg = session.query(UserConfig).filter(
                UserConfig.workspace_id == workspace['id'],
                UserConfig.config_type == 'ai_config'
            ).first()
            
            self.assertIsNotNone(ai_cfg)
            self.assertEqual(ai_cfg.config_data['provider'], "openai")
            self.assertEqual(ai_cfg.config_data['model'], "gpt-3.5-turbo")
        
        print("[PASS] 配置数据迁移测试通过")
    
    def test_data_integrity_after_migration(self):
        """测试迁移后的数据完整性"""
        # 创建测试数据
        workspace = workspace_service.create_workspace("完整性测试工作区")
        
        # 创建包含完整数据的会话
        original_data = {
            "total_logs": 2000,
            "unique_components": 15,
            "duplicate_ratio": 30.5,
            "components": {
                "app": {"count": 1000, "errors": 50},
                "framework": {"count": 800, "errors": 30},
                "system": {"count": 200, "errors": 10}
            },
            "error_categories": {
                "memory_error": [
                    {"timestamp": "2024-01-01T10:00:00", "message": "Memory leak detected"},
                    {"timestamp": "2024-01-01T10:05:00", "message": "Out of memory"}
                ],
                "network_error": [
                    {"timestamp": "2024-01-01T10:10:00", "message": "Connection failed"}
                ]
            }
        }
        
        session = session_service.create_session(
            workspace_id=workspace['id'],
            name="完整性测试会话"
        )
        
        updated_session = session_service.update_session(
            session['id'],
            analysis_results=original_data,
            status="completed",
            tags=["integrity_test"],
            notes="用于测试数据完整性"
        )
        
        # 验证数据完整性
        retrieved_session = session_service.get_session(session['id'])
        
        # 检查所有字段都正确保存和读取
        self.assertEqual(
            retrieved_session['analysis_results']['total_logs'],
            original_data['total_logs']
        )
        self.assertEqual(
            retrieved_session['analysis_results']['unique_components'],
            original_data['unique_components']
        )
        self.assertEqual(
            retrieved_session['analysis_results']['duplicate_ratio'],
            original_data['duplicate_ratio']
        )
        
        # 检查嵌套数据结构
        self.assertEqual(
            retrieved_session['analysis_results']['components']['app']['count'],
            original_data['components']['app']['count']
        )
        
        # 检查数组数据
        self.assertEqual(
            len(retrieved_session['analysis_results']['error_categories']['memory_error']),
            len(original_data['error_categories']['memory_error'])
        )
        
        print("[PASS] 数据完整性测试通过")

def run_migration_tests():
    """运行数据迁移测试"""
    print("[TEST] 开始数据迁移测试...")
    print("=" * 50)
    
    # 创建测试套件
    test_suite = unittest.TestSuite()
    
    # 添加测试用例
    test_cases = [
        'test_legacy_data_import',
        'test_batch_migration',
        'test_configuration_migration',
        'test_data_integrity_after_migration'
    ]
    
    for test_case in test_cases:
        test_suite.addTest(TestDataMigration(test_case))
    
    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(test_suite)
    
    print("=" * 50)
    if result.wasSuccessful():
        print("[SUCCESS] 所有数据迁移测试通过！")
        return True
    else:
        print("[FAIL] 部分测试失败")
        print(f"失败: {len(result.failures)}, 错误: {len(result.errors)}")
        return False

if __name__ == '__main__':
    success = run_migration_tests()
    exit(0 if success else 1)
